/**
 * 分页管理器
 * 实现虚拟滚动和按需加载
 */

interface PaginationConfig {
  pageSize: number;
  preloadPages: number; // 预加载页数
  cachePages: number;   // 缓存页数
}

interface PageData<T> {
  pageNum: number;
  data: T[];
  total: number;
  timestamp: number;
  loading: boolean;
}

interface PaginationState<T> {
  currentPage: number;
  pageSize: number;
  total: number;
  hasMore: boolean;
  loading: boolean;
  error: string | null;
  pages: Map<number, PageData<T>>;
}

export class PaginationManager<T> {
  private state: PaginationState<T>;
  private config: PaginationConfig;
  private fetchFunction: (pageNum: number, pageSize: number) => Promise<{ rows: T[]; total: number }>;
  private readonly CACHE_DURATION = 5 * 60 * 1000; // 5分钟缓存

  constructor(
    fetchFn: (pageNum: number, pageSize: number) => Promise<{ rows: T[]; total: number }>,
    config: Partial<PaginationConfig> = {}
  ) {
    this.fetchFunction = fetchFn;
    this.config = {
      pageSize: 20,
      preloadPages: 1,
      cachePages: 5,
      ...config
    };

    this.state = {
      currentPage: 1,
      pageSize: this.config.pageSize,
      total: 0,
      hasMore: true,
      loading: false,
      error: null,
      pages: new Map()
    };
  }

  /**
   * 获取当前页数据
   */
  getCurrentPageData(): T[] {
    const page = this.state.pages.get(this.state.currentPage);
    return page?.data || [];
  }

  /**
   * 获取所有已加载的数据（用于搜索）
   */
  getAllLoadedData(): T[] {
    const allData: T[] = [];
    const sortedPages = Array.from(this.state.pages.entries())
      .sort(([a], [b]) => a - b);
    
    for (const [, page] of sortedPages) {
      allData.push(...page.data);
    }
    return allData;
  }

  /**
   * 获取分页状态
   */
  getState(): Readonly<PaginationState<T>> {
    return { ...this.state };
  }

  /**
   * 加载指定页
   */
  async loadPage(pageNum: number, force = false): Promise<T[]> {
    // 检查缓存
    const cachedPage = this.state.pages.get(pageNum);
    if (!force && cachedPage && !this.isPageExpired(cachedPage)) {
      return cachedPage.data;
    }

    // 避免重复加载
    if (cachedPage?.loading) {
      return new Promise((resolve) => {
        const checkLoading = () => {
          const page = this.state.pages.get(pageNum);
          if (page && !page.loading) {
            resolve(page.data);
          } else {
            setTimeout(checkLoading, 100);
          }
        };
        checkLoading();
      });
    }

    // 设置加载状态
    this.state.pages.set(pageNum, {
      pageNum,
      data: [],
      total: this.state.total,
      timestamp: Date.now(),
      loading: true
    });

    try {
      const result = await this.fetchFunction(pageNum, this.config.pageSize);
      
      const pageData: PageData<T> = {
        pageNum,
        data: result.rows || [],
        total: result.total,
        timestamp: Date.now(),
        loading: false
      };

      this.state.pages.set(pageNum, pageData);
      this.state.total = result.total;
      this.state.hasMore = pageNum * this.config.pageSize < result.total;
      this.state.error = null;

      // 清理过期缓存
      this.cleanupCache();

      return pageData.data;
    } catch (error) {
      this.state.error = error instanceof Error ? error.message : '加载失败';
      this.state.pages.delete(pageNum);
      throw error;
    }
  }

  /**
   * 跳转到指定页
   */
  async goToPage(pageNum: number): Promise<T[]> {
    if (pageNum < 1) pageNum = 1;
    
    this.state.currentPage = pageNum;
    this.state.loading = true;

    try {
      const data = await this.loadPage(pageNum);
      
      // 预加载相邻页面
      this.preloadAdjacentPages(pageNum);
      
      return data;
    } finally {
      this.state.loading = false;
    }
  }

  /**
   * 下一页
   */
  async nextPage(): Promise<T[]> {
    if (!this.state.hasMore) {
      return this.getCurrentPageData();
    }
    return this.goToPage(this.state.currentPage + 1);
  }

  /**
   * 上一页
   */
  async prevPage(): Promise<T[]> {
    if (this.state.currentPage <= 1) {
      return this.getCurrentPageData();
    }
    return this.goToPage(this.state.currentPage - 1);
  }

  /**
   * 刷新当前页
   */
  async refresh(): Promise<T[]> {
    return this.loadPage(this.state.currentPage, true);
  }

  /**
   * 重置分页器
   */
  reset(): void {
    this.state.currentPage = 1;
    this.state.total = 0;
    this.state.hasMore = true;
    this.state.loading = false;
    this.state.error = null;
    this.state.pages.clear();
  }

  /**
   * 搜索功能（在已加载数据中搜索）
   */
  search(query: string, searchFn: (item: T, query: string) => boolean): T[] {
    if (!query.trim()) {
      return this.getCurrentPageData();
    }

    const allData = this.getAllLoadedData();
    return allData.filter(item => searchFn(item, query.toLowerCase()));
  }

  /**
   * 预加载相邻页面
   */
  private async preloadAdjacentPages(currentPage: number): Promise<void> {
    const preloadPromises: Promise<any>[] = [];

    for (let i = 1; i <= this.config.preloadPages; i++) {
      // 预加载前面的页
      const prevPage = currentPage - i;
      if (prevPage >= 1 && !this.state.pages.has(prevPage)) {
        preloadPromises.push(
          this.loadPage(prevPage).catch(() => {}) // 忽略预加载错误
        );
      }

      // 预加载后面的页
      const nextPage = currentPage + i;
      const maxPage = Math.ceil(this.state.total / this.config.pageSize);
      if (nextPage <= maxPage && !this.state.pages.has(nextPage)) {
        preloadPromises.push(
          this.loadPage(nextPage).catch(() => {}) // 忽略预加载错误
        );
      }
    }

    // 并行预加载，不等待结果
    if (preloadPromises.length > 0) {
      Promise.all(preloadPromises).catch(() => {});
    }
  }

  /**
   * 检查页面是否过期
   */
  private isPageExpired(page: PageData<T>): boolean {
    return Date.now() - page.timestamp > this.CACHE_DURATION;
  }

  /**
   * 清理过期缓存
   */
  private cleanupCache(): void {
    const now = Date.now();
    const pagesToDelete: number[] = [];

    // 找出过期的页面
    for (const [pageNum, page] of this.state.pages.entries()) {
      if (now - page.timestamp > this.CACHE_DURATION) {
        pagesToDelete.push(pageNum);
      }
    }

    // 如果缓存页面太多，删除最旧的
    if (this.state.pages.size > this.config.cachePages) {
      const sortedPages = Array.from(this.state.pages.entries())
        .sort(([, a], [, b]) => a.timestamp - b.timestamp);
      
      const toDelete = sortedPages.slice(0, this.state.pages.size - this.config.cachePages);
      pagesToDelete.push(...toDelete.map(([pageNum]) => pageNum));
    }

    // 删除页面
    pagesToDelete.forEach(pageNum => {
      this.state.pages.delete(pageNum);
    });
  }

  /**
   * 获取统计信息
   */
  getStats() {
    return {
      currentPage: this.state.currentPage,
      totalPages: Math.ceil(this.state.total / this.config.pageSize),
      total: this.state.total,
      cachedPages: this.state.pages.size,
      hasMore: this.state.hasMore,
      loading: this.state.loading
    };
  }
}
